package com.imc.platform.base.pay.service;

import com.alibaba.fastjson.JSON;
import com.imc.api.attence.dao.repository.LessonRepository;
import com.imc.api.attence.pojo.Lesson;
import com.imc.api.order.dao.IOrderMapper;
import com.imc.api.order.pojo.Order;
import com.imc.api.order.pojo.UserOrgAccount;
import com.imc.api.order.repository.IUserOrgAccountRepository;
import com.imc.api.order.repository.IWxMpOrderRepository;
import com.imc.api.order.service.WxOrderService;
import com.imc.api.order.tuple.ConfirmOrder;
import com.imc.core.config.pay.PayConfig;
import com.imc.core.utils.DateUtils;
import com.imc.core.utils.XmlUtils;
import com.imc.platform.base.pay.http.WxPayService;
import com.imc.platform.base.pay.http.tuple.NotifyDto;
import com.imc.platform.base.pay.http.tuple.PayDto;
import com.imc.platform.base.pay.http.tuple.PrePayDto;
import com.imc.platform.base.pay.http.tuple.PrePayParams;
import com.imc.platform.base.user.dao.mapper.IUserMapper;
import com.imc.platform.base.user.dao.repository.UserRepository;
import com.imc.platform.base.user.pojo.User;
import com.twp.common.tuple.ResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.security.Principal;
import java.util.List;
import java.util.Map;

/**
 * Created by tanweiping on 2018/9/28.
 */
@Transactional
@Slf4j
@Service
public class PayService {
    
    @Autowired
    IWxMpOrderRepository iWxMpOrderRepository;

    @Autowired
    WxPayService wxPayService;

    @Autowired
    WxOrderService wxOrderService;

    @Autowired
    PayConfig payConfig;

    @Autowired
    IOrderMapper iOrderMapper;

    @Autowired
    UserRepository userRepository;

    @Autowired
    IUserOrgAccountRepository iUserOrgAccountRepository;

    @Autowired
    IUserMapper iUserMapper;

    @Autowired
    LessonRepository lessonRepository;

    /*
    * tanweiping  2018/11/20 10:15
    * 方法描述：预下单服务
    */
    public PayDto prePayParams(PrePayParams prePayParams, User user,Lesson lesson,int num,List<String> scheduleIdList,String userSubId) throws Exception {
        PrePayDto prePayDto;
            String prePayDto_ = wxPayService.PrePay(
                    prePayParams
            );
            prePayDto = XmlUtils.xmlToBean(prePayDto_, PrePayDto.class);
            if (
                    !prePayDto.getReturn_code().toLowerCase().equals("SUCCESS".toLowerCase())
                            ||
                            !prePayDto.getResult_code().toLowerCase().equals("SUCCESS".toLowerCase())
                    ) {
                throw new Exception(prePayDto.getReturn_msg());
            }

            /*
            order回写
             */

            ConfirmOrder confirmOrder = wxOrderService.postOrder(user, lesson,num,scheduleIdList,userSubId);

            Order order = confirmOrder.getOrder();
            order.setStatus(1);
            order.setPrepayId(prePayDto.getPrepay_id());
            order.setTradeType(prePayDto.getTrade_type());
            order.setTradeNo(prePayParams.getOut_trade_no());
            wxOrderService.save(order);

            PayDto payDto = PayDto.builder()
                    .appId(prePayDto.getAppid())
                    .prepay_id(prePayDto.getPrepay_id())
                    .build();
            payDto.setPaySign(payDto.getMyPaySign(payConfig.getKey()));

        return payDto;
    }
    
    /*
    * tanweiping  2018/9/28 21:51
    * 方法描述：校验订单金额
    */
    public ResultDTO verify(String totalFee, String orderId){
        Order order = iWxMpOrderRepository.findOne(Integer.parseInt(orderId));
        if (order==null) return ResultDTO.builder().isSuccess(false).message("查无此订单").build();
        if (order.getOrderAmount().compareTo(new BigDecimal(totalFee).divide(new BigDecimal(100)))!=0){
            return ResultDTO.builder().isSuccess(false).message("订单金额不匹配").build();
        }
        return ResultDTO.builder().data(order).build();
    }

    /**
     *  支付结果通知
     * @param notifyData    异步通知后的XML数据
     * @return
     */
    public String payBack(String notifyData) {
        String xmlBack="";
        NotifyDto notifyMap = null;
        try {
            notifyMap = XmlUtils.xmlToBean(notifyData,NotifyDto.class);         // 转换成map
                // 签名正确
                // 进行处理。
                // 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
                String  return_code = notifyMap.getReturn_code();//状态
                String out_trade_no = notifyMap.getOut_trade_no();//订单号

                log.info("notifyMap:"+ JSON.toJSONString(notifyMap));

                if(return_code.equals("SUCCESS")){
                    if(out_trade_no!=null){
                        Order order = iWxMpOrderRepository.findAllByTradeNo(out_trade_no);
                        if (order!=null){
//处理订单逻辑
                            /**
                             *          更新数据库中支付状态。
                             *          特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功。
                             *          此处需要判断一下。后面写入库操作的时候再写
                             *
                             */
                            order.setTransactionId(notifyMap.getTransaction_id());
                            order.setStatus(2);
                            iWxMpOrderRepository.save(order);
                            iUserMapper.updateOrgIdByUserSubIdAndOrderId(String.valueOf(order.getId()),order.getUserSubId());

                            /*
                            判断充值,增加用户课时
                             */
                            Map <String, Object> lessonData = iOrderMapper.queryLessonOrder(String.valueOf(order.getId()));

                            if (lessonData!=null&&!lessonData.isEmpty()){
                                String lessonDate = String.valueOf(lessonData.get("lessonDate"));
                                String quantity = String.valueOf(lessonData.get("quantity"));
                                String userId = String.valueOf(lessonData.get("userId"));
                                String orgId = String.valueOf(lessonData.get("orgId"));
                                int classTime = Integer.parseInt(lessonDate)*Integer.parseInt(quantity);

                                String date = DateUtils.getCurrentDate();
                                UserOrgAccount userOrgAccount_ = iUserOrgAccountRepository.findAllByUserIdAndOrgId(userId,orgId);

                                if (userOrgAccount_==null){
                                    userOrgAccount_ = UserOrgAccount.builder().lessonAccount(0).userId(userId).orgId(orgId).createTime(date).updateTime(date).build();
                                }
                                userOrgAccount_.setLessonAccount(userOrgAccount_.getLessonAccount().intValue()+classTime);
                                iUserOrgAccountRepository.save(userOrgAccount_);

                            }

                            log.info(">>>>>支付成功");

                            log.info("微信手机支付回调成功订单号:{}",out_trade_no);
                            xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                        }

                    }else {
                        log.info("微信手机支付回调失败订单号:{}",out_trade_no);
                        xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
                    }

                }
                return xmlBack;
        } catch (Exception e) {
            log.error("手机支付回调通知失败",e);
            xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        return xmlBack;
    }
}
